package org.jeecg.modules.online.cgreport.util;

import java.io.StringReader;
import java.util.*;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.SimpleNode;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.*;

/**
 * @author wangshuai
 * @description: SQL字段解析
 * @date 2021-07-15
 */
public class CgReportSqlFiledParseUtils {

    /**
     * 该方法会把select后面所有字段都解析出来
     * @param parsedSql
     * @return
     */
    public static Map<String, Object> SqlFiledResolution(String parsedSql) {
        Map<String, Object> mapRes = new HashMap<>();
        Select select = null;
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        try {
            select = (Select)parserManager.parse(new StringReader(parsedSql));
        } catch (JSQLParserException jsqlParserException) {
            jsqlParserException.printStackTrace();
        }
        PlainSelect plain;
        // 处理union的情况
        SelectBody selectBody = select.getSelectBody();
        List<Map<String, Object>> list = new ArrayList<>();
        if (selectBody instanceof SetOperationList) {
            SetOperationList selectBodyList = (SetOperationList)selectBody;
            List<SelectBody> selects = selectBodyList.getSelects();
            for (int i = 0; i < selects.size(); i++) {
                plain = (PlainSelect)selects.get(i);
                // 获取字段名的集合
                List<String> tableAndColumns = getTableAndColumns(plain);
                // 将list循环放到map中(key和value均是字段名)
                getMapFiled(mapRes, tableAndColumns);
            }
        }
        if (selectBody instanceof PlainSelect) {
            plain = (PlainSelect)selectBody;
            List<String> tableAndColumns = getTableAndColumns(plain);
            getMapFiled(mapRes, tableAndColumns);
        }
        return mapRes;
    }

    private static void getMapFiled(Map<String, Object> mapRes, List<String> tableAndColumns) {
        for (String str : tableAndColumns) {
            //排除*不展示
            if (!"*".equals(str)) {
                mapRes.put(str, str);
            }
        }
    }

    public static List<String> getTableAndColumns(PlainSelect plain) {
        // 获取select后面的语句
        List<SelectItem> selectItems = plain.getSelectItems();
        List<String> items = new ArrayList<>();
        if (selectItems != null) {
            for (SelectItem selectItem : selectItems) {
                if (selectItem instanceof SelectExpressionItem) {
                    SelectExpressionItem selectExpressionItem = (SelectExpressionItem)selectItem;
                    String columnName = "";
                    Alias alias = selectExpressionItem.getAlias();
                    Expression expression = selectExpressionItem.getExpression();
                    if (expression instanceof CaseExpression) {
                        // case表达式
                        columnName = alias.getName();
                    } else if (expression instanceof LongValue || expression instanceof StringValue
                        || expression instanceof DateValue || expression instanceof DoubleValue) {
                        // 值表达式
                        columnName = Objects.nonNull(alias.getName()) ? alias.getName()
                            : expression.getASTNode().jjtGetValue().toString();
                    } else if (expression instanceof TimeKeyExpression) {
                        // 日期
                        columnName = alias.getName();
                    } else {
                        if (alias != null) {
                            columnName = alias.getName();
                        } else {
                            SimpleNode node = expression.getASTNode();
                            Object value = node.jjtGetValue();
                            if (value instanceof Column) {
                                columnName = ((Column)value).getColumnName();
                            } else if (value instanceof Function) {
                                columnName = value.toString();
                            } else {
                                // 增加对select 'aaa' from table; 的支持
                                columnName = String.valueOf(value);
                                columnName = columnName.replace("'", "");
                                columnName = columnName.replace("\"", "");
                                columnName = columnName.replace("`", "");
                            }
                        }
                    }

                    columnName = columnName.replace("'", "");
                    columnName = columnName.replace("\"", "");
                    columnName = columnName.replace("`", "");

                    items.add(columnName);
                } else if (selectItem instanceof AllTableColumns) {
                    AllTableColumns allTableColumns = (AllTableColumns)selectItem;
                    items.add(allTableColumns.toString());
                } else {
                    items.add(selectItem.toString());
                }
            }
        }
        return items;
    }
}
